/**
 *  Describe:
 *  Created by xjc on 2019/7/30
 */

/*
    导入数据格式：
    {
     title:''
     code:0/1,
     data:[],//数据json
     total:[],//合计项
     showHeader:props/true,//展示表头
     columns:[{
          * type:'date','number','string'
          title:自定义,
          * dataIndex: 自定义,
          width:不设定自动排版/自定义,
          align:不设定自动'center'/自定义,
          fixed:false/'left','right',
          sorter:false/true
          'date':排序(a, b) => DateStamp(a.tradedate) - DateStamp(b.tradedate),
          'number':排序(a, b) => a.gainbeta - b.gainbeta,
          'string':排序(a, b) => 排序(a, b) => (a, b) => {
              let c = [a.stock , b.stock].sort();
              if(c[0] === a.stock){
                return 1;
              }else{
                return -1;
              }
            },
          filterAuto:false/true,
          filter:props,
          render:false/自定义,
          search:false/true,//和filters不共存
          editable:false/true/{
                  filter:[
                    {
                      text: '属于',
                      value: '0',
                    },{
                      text: '不属于',
                      value: '1',
                    },
                  ],
                },
          render:props,
          //renderAuto:
            type:'number'
            {
               reserve:3,//保留尾数
               symbol:'$',//添加符号
            }
            type:'date'
            {
                transition: 'Y-M-D h:m:s'
            }
     }]

   }
*/

// 源插件
import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import moment from 'moment';
import router from 'umi/router';
import {
  numAdd,
  numSub,
  numMulti,
  numDiv,
  NumberDivide,
  DateDiff,
  FormatnumberZero,
  Mover,
  DateStamp,
  isArray,
} from '@/function.js';

// 视图插件
import {
  BackTop,
  Empty,
  Spin,
  Row,
  Col,
  Card,
  Form,
  Input,
  Select,
  Icon,
  Button,
  Dropdown,
  Menu,
  InputNumber,
  DatePicker,
  Modal,
  message,
  Badge,
  Divider,
  Steps,
  Radio,
  Upload,
} from 'antd';

// 外部组件
import UpgradeStandardTable from '@/components/UpgradeReportStandardTable';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import Loading from '@/components/Loading/Loading';

// css OR less预编译器
import _pull from 'lodash/pull';
import _uniq from 'lodash/uniq';
import _map from 'lodash/map';
import styles from './All.less';

// 格式化日期，如月、日、时、分、秒保证为2位数
function formatNumber(n) {
  n = n.toString();
  return n[1] ? n : `0${n}`;
}
// 参数number为毫秒时间戳，format为需要转换成的日期格式
function formatTime(number, format) {
  const time = new Date(number);
  const newArr = [];
  const formatArr = ['Y', 'M', 'D', 'h', 'm', 's'];
  newArr.push(time.getFullYear());
  newArr.push(formatNumber(time.getMonth() + 1));
  newArr.push(formatNumber(time.getDate()));

  newArr.push(formatNumber(time.getHours()));
  newArr.push(formatNumber(time.getMinutes()));
  newArr.push(formatNumber(time.getSeconds()));

  for (const i in newArr) {
    format = format.replace(formatArr[i], newArr[i]);
  }
  return format;
}

// 图片

const SelectOption = Select.Option;

const EditableContext = React.createContext();

const EditableRow = ({ form, index, ...props }) => (
  <EditableContext.Provider value={form}>
    <tr {...props} />
  </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);

class EditableCell extends React.Component {
  state = {
    editing: false,
  };

  toggleEdit = flag => {
    if (flag) return;
    const editing = !this.state.editing;
    this.setState({ editing }, () => {
      if (editing) {
        this.input.focus();
      }
    });
  };

  save = e => {
    const { record, handleSave } = this.props;
    this.form.validateFields((error, values) => {
      if (error && error[e.currentTarget.id]) {
        return;
      }
      this.toggleEdit();
      handleSave(record, values);
    });
  };

  noSaveOut = e => {
    const { record, handleSave } = this.props;
    this.form.validateFields((error, values) => {
      if (error && error[e.currentTarget.id]) {
        return;
      }
      this.toggleEdit();
      // handleSave({ ...record, ...values });
    });
  };

  renderCell = form => {
    this.form = form;
    const { children, dataIndex, record, title, firstIndex, editable } = this.props;
    const { editing } = this.state;
    let nullFlag = false;
    if (record[dataIndex] === null) {
      nullFlag = true;
    }
    return editing ? (
      <Form.Item style={{ margin: 0 }}>
        {editable.filter
          ? form.getFieldDecorator(dataIndex, {
              initialValue: record[dataIndex].toString(),
            })(
              <Select
                ref={node => (this.input = node)}
                style={{ width: '80%' }}
                onSelect={this.save}
                onBlur={this.noSaveOut}
              >
                {editable.filter.map(item => {
                  return <SelectOption value={item.value}>{item.text}</SelectOption>;
                })}
              </Select>
            )
          : form.getFieldDecorator(dataIndex, {
              rules: [
                /* {
                 required: true,
                 message: `${title} is required.`,
               }, */
              ],
              initialValue: record[dataIndex] || 0,
            })(
              <Input
                ref={node => (this.input = node)}
                onPressEnter={this.save}
                onBlur={this.noSaveOut}
                style={{ width: '80%', height: '90%' }}
              />
            )}
      </Form.Item>
    ) : (
      <div
        className={styles.editableCellValueWrap}
        style={{ padding: nullFlag ? '5px 12px' : '' }}
        onClick={this.toggleEdit.bind(this, record[firstIndex] === '合计')}
      >
        {children}
      </div>
    );
  };

  render() {
    const {
      editable,
      dataIndex,
      title,
      record,
      index,
      handleSave,
      firstIndex,
      children,
      ...restProps
    } = this.props;
    return (
      <td {...restProps}>
        {editable ? (
          <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
        ) : (
          children
        )}
      </td>
    );
  }
}

/**
 *  Describe:数据连接
 *  Created by xjc on 2019/5/15
 */

class StandardTablePro extends PureComponent {
  componentWillMount() {}

  /**
   *  Describe:当前状态
   *  Created by xjc on 2019/5/15
   */

  state = {
    listLoading: false, // 加载状态
    selectedRows: [], // 选择行
    formValues: {
      num: 10,
      page: 1,
      total: 0,
    }, // 表格参数
    record: {}, // 当前行内容
    searchText: '', // 搜索内容
    columns: [], // 表头处理结果
    currentDataSource: [], // 表剩余数据
    minFlag: false, // 最小加载时间flag
  };

  columns = null;

  firstIndex = null;

  data = [];

  /**
   *  Describe:本地搜索
   *  Created by xjc on 2019/6/4
   */

  getColumnSearchProps = dataIndex => ({
    filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
      <div style={{ padding: 8 }}>
        <Input
          ref={node => {
            this.searchInput = node;
          }}
          placeholder={`Search ${dataIndex}`}
          value={selectedKeys[0]}
          onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
          onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
          style={{ width: 188, marginBottom: 8, display: 'block' }}
        />
        <Button
          type="primary"
          onClick={() => this.handleSearch(selectedKeys, confirm)}
          icon="search"
          size="small"
          style={{ width: 80, marginRight: 8 }}
        >
          搜索
        </Button>
        <Button onClick={() => this.handleReset(clearFilters)} size="small" style={{ width: 80 }}>
          重置
        </Button>
      </div>
    ),
    filterIcon: filtered => (
      <Icon type="search" style={{ color: filtered ? '#1880ff' : '#181816', fontWeight: '700' }} />
    ),
    onFilter: (value, record) => {
      if (record[this.firstIndex] === '合计') {
        return true;
      }
      return record[dataIndex] === null || typeof record[dataIndex] === 'undefined'
        ? ''
        : record[dataIndex]
            .toString()
            .toLowerCase()
            .includes(value.toLowerCase());
    },
    onFilterDropdownVisibleChange: visible => {
      if (visible) {
        setTimeout(() => this.searchInput.select());
      }
    },
    render: text => <span>{text}</span>,
  });

  handleSearch = (selectedKeys, confirm) => {
    confirm();
    this.setState({ searchText: selectedKeys[0] });
  };

  handleReset = clearFilters => {
    clearFilters();
    this.setState({ searchText: '' });
  };

  // 排序算法
  getSorter(a, b, type, dataIndex, firstIndex) {
    if (b[firstIndex] === '合计') {
      return 0;
    }
    if (type === 'date') {
      return DateStamp(a[dataIndex]) - DateStamp(b[dataIndex]);
    }
    if (type === 'number') {
      return a[dataIndex] - b[dataIndex];
    }
    if (type === 'string') {
      const c = [a[dataIndex], b[dataIndex]].sort();
      if (c[0] === a[dataIndex]) {
        return 1;
      }
      return -1;
    }
  }

  // 筛选算法
  getFilters(data, dataIndex) {
    const filters = _pull(_uniq(_map(data, dataIndex)), null, undefined);
    const reFilters = filters.map(i => {
      return { text: i, value: i };
    });
    return reFilters;
  }

  // 第一次拿取表头
  getColumns(columns, data) {
    const that = this;
    let reColumns = columns.map(item => {
      if (that.firstIndex === null) {
        that.firstIndex = item.dataIndex;
      }
      let reItem = {};
      if (item.search) {
        reItem = {
          title: item.title || '',
          dataIndex: item.dataIndex,
          width: item.width || 100,
          align: item.align || 'center',
          fixed: item.fixed || false,
          editable: item.editable || false,
          ...that.getColumnSearchProps(item.dataIndex),
        };
      } else {
        reItem = {
          title: item.title || '',
          dataIndex: item.dataIndex,
          width: item.width || 100,
          align: item.align || 'center',
          fixed: item.fixed || false,
          editable: item.editable || false,
        };
      }

      if (item.filterAuto) {
        reItem.filters = that.getFilters(data, item.dataIndex);
        reItem.onFilter = (value, record) => {
          if (record[that.firstIndex] === '合计') {
            return true;
          }
          if (record[item.dataIndex] !== undefined) {
            return record[item.dataIndex].toString().indexOf(value) === 0;
          }
        };
      }
      if (item.filters) {
        reItem.filters = item.filters;
        reItem.onFilter = (value, record) => {
          if (record[that.firstIndex] === '合计') {
            return true;
          }
          if (record[item.dataIndex] !== undefined) {
            return record[item.dataIndex].toString().indexOf(value) === 0;
          }
        };
      }

      if (item.sorter) {
        reItem.sorter = (a, b) => {
          return that.getSorter(a, b, item.type, item.dataIndex, that.firstIndex);
        };
      }

      if (item.colSpan) {
        reItem.colSpan = item.colSpan;
      }
      if (item.rowSpan) {
        reItem.rowSpan = item.rowSpan;
      }

      if (item.render) {
        reItem.render = item.render;
      } else if (item.type === 'number') {
        reItem.render = (value, row, index) => {
          return <span>{value !== '合计' ? NumberDivide(value) : '合计'}</span>;
        };
      }
      return reItem;
    });
    reColumns = reColumns.map(col => {
      if (!col.editable) {
        return col;
      }
      return {
        ...col,
        onCell: record => ({
          record,
          editable: col.editable,
          dataIndex: col.dataIndex,
          firstIndex: this.firstIndex,
          title: col.title,
          handleSave: that.handleSave,
        }),
      };
    });
    return reColumns;
  }

  // 编辑保存
  handleSave = (row, values) => {
    this.props.handleSave(row, values);
  };

  // 拿数据做合计
  getData(data, total, currentDataSource) {
    let flag = false;
    if (total.length === 0) {
      this.setState({
        currentDataSource: currentDataSource || data,
      });
      return data;
    }
    if (data[0] && data[0][this.firstIndex] === '合计') {
      flag = true;
      data.splice(0, 1);
    }
    const unshiftData = {};
    if (flag) {
      for (let i = 0; i < currentDataSource.length; i++) {
        for (let j = 0; j < total.length; j++) {
          const totalIndex = total[j];

          if (isArray(totalIndex)) {
            if (i === 0) {
              unshiftData[totalIndex[0]] = 0;
              continue;
            }
            totalIndex.map(k => {
              unshiftData[totalIndex[0]] = mathService.add(
                unshiftData[totalIndex[0]],
                currentDataSource[i][k] || 0
              );
            });
            continue;
          }
          if (i === 0) {
            unshiftData[totalIndex] = 0;
            continue;
          }
          unshiftData[totalIndex] = mathService.add(
            unshiftData[totalIndex],
            currentDataSource[i][totalIndex] || 0
          );
        }
      }
      unshiftData[this.firstIndex] = '合计';
      data.unshift(unshiftData);
    } else {
      for (let i = 0; i < data.length; i++) {
        for (let j = 0; j < total.length; j++) {
          const totalIndex = total[j];
          if (isArray(totalIndex)) {
            if (i === 0) {
              unshiftData[totalIndex[0]] = 0;
            }
            totalIndex.map(k => {
              unshiftData[totalIndex[0]] = mathService.add(
                unshiftData[totalIndex[0]],
                data[i][k] || 0
              );
            });
            continue;
          }
          if (i === 0) {
            unshiftData[totalIndex] = 0;
          }
          unshiftData[totalIndex] = mathService.add(
            unshiftData[totalIndex],
            data[i][totalIndex] || 0
          );
        }
      }
      unshiftData[this.firstIndex] = '合计';
      data.unshift(unshiftData);
      this.setState(
        {
          currentDataSource: data,
        },
        () => {
          const mover = [];
          for (let i = 0; i < document.querySelectorAll('.ant-table-body').length; i++) {
            mover[i] = new Mover(document.querySelectorAll('.ant-table-body')[i]);
          }
        }
      );
    }
  }

  // 剩余数据修改触发
  handleStandardTableChange = (pagination, filtersArg, sorter, extra) => {
    const {
      dataSource: { total },
    } = this.props;
    /*  const {formValues} = this.state;
      formValues.page = pagination.current;
      formValues.pagesize = pagination.pageSize;
      const params = {
        ...formValues,
      }; */
    const data = this.props.dataSource.data || [];
    this.setState({
      currentDataSource: extra.currentDataSource,
    });
    this.getData(data, total, extra.currentDataSource);
  };

  /**
   *  Describe:视图
   *  Created by xjc on 2019/5/15
   */

  render() {
    const {
      dataSource: { total, code, columns, title, titleTotal, showHeader },
      rowSetKey,
      closeScroll,
      doubleClick,
    } = this.props;
    const data = this.props.dataSource.data || [];
    const { listLoading, selectedRows, currentDataSource, minFlag } = this.state;
    const components = {
      body: {
        row: EditableFormRow,
        cell: EditableCell,
      },
    };
    let tableWidth = 0;

    if (
      (this.columns === null ||
        (total.length !== 0 &&
          (data && data.length !== 0) &&
          data[0][this.firstIndex] !== '合计')) &&
      code === 1
    ) {
      this.columns = this.getColumns(columns, data);
      this.getData(data, total);
    }
    if (columns) {
      columns.map(i => {
        tableWidth += i.width || 100;
      });
    }
    let scroll = {};
    /*    closeScroll?{}
            :<10?{}:?{x:tableWidth*1.1,y:668}:{y:668}} */
    if (closeScroll) {
      scroll = false;
    } else if (columns) {
      if (columns.length > 8 || !window.IsPC) {
        scroll.x = tableWidth * 1.1;
      }
      if (currentDataSource.length > 10) {
        scroll.y = 668;
      }
    }
    return (
      <div>
        {code === 1 && minFlag ? (
          title ? (
            <div>
              <UpgradeStandardTable
                components={components}
                bordered
                title={() => {
                  if (title) {
                    return (
                      <div style={{ textAlign: 'center', fontSize: '0.95rem' }}>
                        <span style={{ marginRight: 10 }}>{title}</span>
                        <span>
                          {titleTotal === false
                            ? ''
                            : `共计：${
                                total.length === 0
                                  ? currentDataSource.length
                                  : currentDataSource.length - 1 <= 0
                                  ? 0
                                  : currentDataSource.length - 1
                              }`}
                        </span>
                      </div>
                    );
                  }
                  return false;
                }}
                selectedRows={selectedRows}
                loading={listLoading}
                data={{ list: data }}
                showHeader={showHeader === false ? showHeader : true}
                columns={this.columns}
                style={{ tableLayout: 'fixed' }}
                className={total.length === 0 ? styles.TableLayout : styles.TableLayoutFixedOne}
                pagination={false}
                onChange={this.handleStandardTableChange}
                scroll={scroll}
                onRow={record => {
                  const res = record;
                  if (doubleClick) {
                    return {
                      onClick: event => {
                        doubleClick(res);
                      },
                    };
                  }
                }}
                rowClassName={
                  rowSetKey
                    ? (record, index) => {
                        if (rowSetKey(record, index)) {
                          return styles.keyTableBackground;
                        }
                        return record.stock === '合计'
                          ? styles.statisticssTableBackground
                          : styles.ffffff;
                      }
                    : (record, index) => {
                        return record.stock === '合计'
                          ? styles.statisticssTableBackground
                          : styles.ffffff;
                      }
                }
              />
            </div>
          ) : (
            <div>
              <UpgradeStandardTable
                components={components}
                bordered
                selectedRows={selectedRows}
                loading={listLoading}
                data={{ list: data }}
                showHeader={showHeader === false ? showHeader : true}
                columns={this.columns}
                style={{ tableLayout: 'fixed' }}
                className={total.length === 0 ? styles.TableLayout : styles.TableLayoutFixedOne}
                pagination={false}
                onChange={this.handleStandardTableChange}
                scroll={scroll}
                onRow={record => {
                  const res = record;
                  if (doubleClick) {
                    return {
                      onClick: event => {
                        doubleClick(res);
                      },
                    };
                  }
                }}
                rowClassName={
                  rowSetKey
                    ? (record, index) => {
                        if (rowSetKey(record, index)) {
                          return styles.keyTableBackground;
                        }
                        return record.stock === '合计'
                          ? styles.statisticssTableBackground
                          : styles.ffffff;
                      }
                    : (record, index) => {
                        return record.stock === '合计'
                          ? styles.statisticssTableBackground
                          : styles.ffffff;
                      }
                }
              />
            </div>
          )
        ) : (
          <Loading />
        )}
      </div>
    );
  }

  componentDidMount() {
    window.timerMin = setTimeout(() => {
      this.setState({
        minFlag: true,
      });
    }, 600);
  }

  componentWillUnmount() {}
}

export default StandardTablePro;
